package ddbtasktracker.datastore;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.mybatis.spring.SqlSessionTemplate;

import tasktracker.abstraction.TaskProgressInfo;
import tasktracker.core.abstraction.FrameworkTrackedTask;
import tasktracker.core.abstraction.TaskProperty;
import tasktracker.core.abstraction.TaskStoreProvider;

public class MySQLTaskStoreProvider implements TaskStoreProvider {

	private static final String NAMESPACE = "ddbtasktracker.taskstore.";

	SqlSessionTemplate sqlSessionTemplate;

	public MySQLTaskStoreProvider(SqlSessionTemplate sqlSessionTemplate) {
		this.sqlSessionTemplate = sqlSessionTemplate;
	}

	@Override
	public void addTask(FrameworkTrackedTask task) {
		sqlSessionTemplate.insert(NAMESPACE + "addTask", task);
		addTaskProperties(task.getGuid(), task.getProperties());
	}

	public void addTaskProperties(String guid, Map<String, String> properties) {
		if (properties == null)
			return;
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("guid", guid);
		for (Map.Entry<String, String> entry : properties.entrySet()) {
			paramMap.put("key", entry.getKey());
			paramMap.put("value", entry.getValue());
			sqlSessionTemplate.insert(NAMESPACE + "setTaskProperty", paramMap);
		}
	}

	@Override
	public FrameworkTrackedTask getTask(String guid) {
		FrameworkTrackedTask task = sqlSessionTemplate.selectOne(NAMESPACE + "getTask", guid);
		if (task == null)
			return null;
		task.setProperties(getTaskPropertiesMap(guid));
		return task;
	}

	public Map<String, String> getTaskPropertiesMap(String guid) {
		Map<String, String> properties = new HashMap<String, String>();
		List<TaskProperty> list = getTaskProperties(guid);
		for (TaskProperty taskProperty : list) {
			properties.put(taskProperty.getKey(), taskProperty.getValue());
		}
		return properties;
	}
	public List<TaskProperty> getTaskProperties(String guid) {
		return sqlSessionTemplate.selectList(NAMESPACE + "getTaskProperties", guid);
	}

	@Override
	public void removeTask(String guid) {
		sqlSessionTemplate.delete(NAMESPACE + "removeTaskProperties", guid);
		sqlSessionTemplate.delete(NAMESPACE + "removeTask", guid);
	}

	@Override
	public void updateStartTime(String guid, Date currentDatetimeUtc) {
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("guid", guid);
		paramMap.put("startedDatetime", currentDatetimeUtc);
		sqlSessionTemplate.update(NAMESPACE + "updateStartTime", paramMap);
	}

	@Override
	public List<FrameworkTrackedTask> getTasksByStatus(int status) {
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("status", status);
		return sqlSessionTemplate.selectList(NAMESPACE + "getTasksByStatus", paramMap);
	}

	@Override
	public void updateStatus(String guid, int status) {
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("guid", guid);
		paramMap.put("status", status);
		sqlSessionTemplate.update(NAMESPACE + "updateStatus", paramMap);
	}

	@Override
	public void updateStatus(List<String> guids, int status) {
		if (guids == null || guids.isEmpty())
			return;
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("guids", guids);
		paramMap.put("status", status);
		sqlSessionTemplate.update(NAMESPACE + "updateStatusList", paramMap);
	}

	@Override
	public boolean checkAndUpdateStatus(String guid, int status, int oldStatus) {
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("guid", guid);
		paramMap.put("status", status);
		paramMap.put("oldStatus", oldStatus);
		return 0 != sqlSessionTemplate.update(NAMESPACE + "checkAndUpdateStatus", paramMap);
	}

	@Override
	public void checkAndUpdateStatus(List<String> guids, int status, int oldStatus) {
		if (guids == null || guids.isEmpty())
			return;
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("guids", guids);
		paramMap.put("status", status);
		paramMap.put("oldStatus", oldStatus);
		sqlSessionTemplate.update(NAMESPACE + "updateStatusList", paramMap);
	}

	@Override
	public void setResult(String guid, int status, Date currentDatetimeUtc, String primaryResult,
			String secondaryResult) {
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("guid", guid);
		paramMap.put("status", status);
		paramMap.put("primaryResult", primaryResult);
		paramMap.put("secondaryResult", secondaryResult);
		paramMap.put("completedDatetime", currentDatetimeUtc);
		sqlSessionTemplate.update(NAMESPACE + "setResult", paramMap);
	}

	@Override
	public void setResult(List<String> guids, int status, Date currentDatetimeUtc, String primaryResult,
			String secondaryResult) {
		if (guids == null || guids.isEmpty())
			return;
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("guids", guids);
		paramMap.put("status", status);
		paramMap.put("primaryResult", primaryResult);
		paramMap.put("secondaryResult", secondaryResult);
		paramMap.put("completedDatetime", currentDatetimeUtc);
		sqlSessionTemplate.update(NAMESPACE + "setResultList", paramMap);
	}

	@Override
	public void storeProgress(String guid, TaskProgressInfo progress) {
		// nop
	}

	@Override
	public void removeProgress(String guid) {
		// nop
	}

}
